package com.tqz.rc.api;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.tqz.rc.common.constant.Constants;
import com.tqz.rc.common.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * @author tianqingzhao
 * @since 2021/9/27 11:02
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class ServiceInfo {

    // 服务名称，该服务名称是使用 groupName@@serviceName 拼接的
    private String serviceName;

    // 组名
    private String groupName;

    // 集群的名称，多个以英文逗号拼接
    private String clusters;

    // 缓存时间
    private long cacheMillis = 1000L;

    // 该服务下所有的实例
    private List<Instance> hosts = new ArrayList<Instance>();

    // 设置最后的引用时间
    private long lastRefTime = 0L;

    // 校验md5 目前版本没什么用
    private String checksum = "";

    // 是否是所有的ip
    private volatile boolean allIPs = false;

    // 是否达到保护阈值，根据健康节点的数量除以节点总数量是否大于该服务的保护阈值去判断
    private volatile boolean reachProtectionThreshold = false;

    // 当前对象转json的字符串
    private String jsonFromServer;

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public String getClusters() {
        return clusters;
    }

    public void setClusters(String clusters) {
        this.clusters = clusters;
    }

    public long getCacheMillis() {
        return cacheMillis;
    }

    public void setCacheMillis(long cacheMillis) {
        this.cacheMillis = cacheMillis;
    }

    public List<Instance> getHosts() {
        return hosts;
    }

    public void setHosts(List<Instance> hosts) {
        this.hosts = hosts;
    }

    public long getLastRefTime() {
        return lastRefTime;
    }

    public void setLastRefTime(long lastRefTime) {
        this.lastRefTime = lastRefTime;
    }

    public String getChecksum() {
        return checksum;
    }

    public void setChecksum(String checksum) {
        this.checksum = checksum;
    }

    public boolean isAllIPs() {
        return allIPs;
    }

    public void setAllIPs(boolean allIPs) {
        this.allIPs = allIPs;
    }

    public boolean isReachProtectionThreshold() {
        return reachProtectionThreshold;
    }

    public void setReachProtectionThreshold(boolean reachProtectionThreshold) {
        this.reachProtectionThreshold = reachProtectionThreshold;
    }

    public String getJsonFromServer() {
        return jsonFromServer;
    }

    public void setJsonFromServer(String jsonFromServer) {
        this.jsonFromServer = jsonFromServer;
    }

    public int ipCount() {
        return hosts.size();
    }

    public String getKey() {
        String groupedServiceName = getGroupedServiceName();
        return getKey(groupedServiceName, clusters);
    }

    public static String getKey(String groupedServiceName, String clusters) {
        if (!StringUtils.isEmpty(clusters)) {
            return groupedServiceName + Constants.SERVICE_INFO_SPLITER + clusters;
        }

        return groupedServiceName;
    }

    private String getGroupedServiceName() {
        String serviceName = this.serviceName;
        if (!StringUtils.isEmpty(groupName) && !serviceName.contains(Constants.SERVICE_INFO_SPLITER)) {
            serviceName = groupName + Constants.SERVICE_INFO_SPLITER + serviceName;
        }
        return serviceName;
    }

    public boolean validate() {
        if (isAllIPs()) {
            return true;
        }

        if (hosts == null) {
            return false;
        }

        List<Instance> validHosts = new ArrayList<Instance>();
        for (Instance host : hosts) {
            if (!host.isHealthy()) {
                continue;
            }

            for (int i = 0; i < host.getWeight(); i++) {
                validHosts.add(host);
            }
        }
        //No valid hosts, return false.
        return !validHosts.isEmpty();
    }
}
